package com.itsu.app.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import com.itsu.app.config.HuanXinConfig;
import com.itsu.app.exception.MyException;
import com.itsu.app.interceptor.UserThreadLocal;
import com.itsu.interfaces.entity.HuanxinUser;
import com.itsu.interfaces.entity.UserEntity;
import com.itsu.interfaces.entity.UserFreeze;
import com.itsu.interfaces.entity.UserLogin;
import com.itsu.interfaces.service.UserFreezeService;
import com.itsu.interfaces.service.UserLoginService;
import com.itsu.interfaces.service.UserService;
import com.itsu.pojo.constants.Constants;
import com.itsu.pojo.enums.ResultCode;
import com.itsu.pojo.results.ErrorResult;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class AppUserService {

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    @Reference
    UserService userService;

    @Autowired
    RequestService requestService;

    @Autowired
    AppHuanxinUserService appHuanxinUserService;

    @Autowired
    HuanXinConfig huanXinConfig;

    @Reference
    UserLoginService userLoginService;

    @Reference
    UserFreezeService userFreezeService;

    //发送短信验证码
    public void sendMag(String mobile) {
        //校验手机号
        if (!Validator.isMobile(mobile)) {
            throw new MyException(new ErrorResult(ResultCode.PHONE_VALIDATOR_ERROR));
        }
        //通过Redis——KEY获取验证码信息
        String redisKey = Constants.SMS_CODE + mobile;
        String code = redisTemplate.opsForValue().get(redisKey);
//        String validatorCode;
//        //判断验证码信息是否为空
//        if (StrUtil.isNotBlank(code)) {
//            //不为空时，重新将Redis中的旧验证码发给用户
//            validatorCode = code;
//        } else {
//            //为空时，生成新的验证码发送客户
//            validatorCode = RandomUtil.randomNumbers(6);
//        }

        //发送验证码
//        if(!SendSmsUtil.sendSms(mobile,validatorCode)) {
//            throw new MyException(new ErrorResult(ResultCode.SEND_MESSAGE_FAIL));
//        }

        if (StrUtil.isNotBlank(code)) {
            throw new MyException(new ErrorResult(ResultCode.VALIDATOR_CODE_NOT_TIMEOUT));
        }

        code = "123456";

        //验证码存入Redis，有效期为5分钟
        redisTemplate.opsForValue().set(redisKey, code, 5, TimeUnit.MINUTES);
    }

    //登录校验
    public Map<String, Object> loginVerification(String phone, String verificationCode) {
        //校验手机号
        if (!Validator.isMobile(phone)) {
            throw new MyException(new ErrorResult(ResultCode.PHONE_VALIDATOR_ERROR));
        }

        //获取Redis中的验证码
        String code = redisTemplate.opsForValue().get(Constants.SMS_CODE + phone);
        //Redis中验证码为空
        if (StrUtil.isBlank(code)) {
            throw new MyException(new ErrorResult(ResultCode.VALIDATOR_CODE_TIMEOUT));
        }

        //输入验证码为空或与Redis中的验证码不一致
        if (StrUtil.isBlank(verificationCode) || !code.equals(verificationCode)) {
            throw new MyException(new ErrorResult(ResultCode.VALIDATOR_CODE_ERROR));
        }

        //通过手机号查询用户
        UserEntity userEntity = userService.findByMobile(phone);
        Map<String, Object> date = new HashMap<>();
        date.put("isNew", false);
        //用户未空
        if (ObjectUtil.isEmpty(userEntity)) {
            //设置isnew为TRUE
            date.put("isNew", true);
            //添加此用户
            userEntity = userService.addUser(UserEntity.builder()
                    .mobile(phone)
                    .password(SecureUtil.md5(Constants.INIT_PASSWORD))
                    .created(new Date())
                    .updated(new Date())
                    .build());

            //第三方 环信通信 创建用户
            HttpResponse response = requestService.execute(huanXinConfig.getUrl() + huanXinConfig.getOrgName() + "/" + huanXinConfig.getAppName() + "/users"
                    , JSONUtil.createObj()
                            .set("username", "HX_" + userEntity.getId())
                            .set("password", SecureUtil.md5(userEntity.getMobile()))
                            .set("nickname", userEntity.getMobile())
                            .toString()
                    , Method.POST);

            if (!response.isOk()) {
                throw new MyException(new ErrorResult(ResultCode.USER_REGIT_ERROR));
            }

            //本地存储环信信息
            appHuanxinUserService.addUser(HuanxinUser.builder()
                    .userId(userEntity.getId())
                    .username("HX_" + userEntity.getId())
                    .password(SecureUtil.md5(userEntity.getMobile()))
                    .created(userEntity.getCreated())
                    .updated(userEntity.getCreated())
                    .build());

        }

        //添加用户登录信息
        UserLogin userLogin = new UserLogin();
        userLogin.setUserId(userEntity.getId());
        userLogin.setLoginTime(new Date());
        userLogin.setOutTime(DateUtils.addHours(new Date(), 1));
        userLoginService.addUserLogin(userLogin);

        //是否解冻
        UserFreeze userFreeze = userFreezeService.findByUid(userEntity.getId());
        if (userFreeze.getThawTime().getTime() <= System.currentTimeMillis()) {
            userFreezeService.deleteUserFreezeByUid(userEntity.getId());
        } else {
            throw new MyException(new ErrorResult(ResultCode.USER_REGIT_ERROR));
        }

        //设置token
        Map<String, Object> jwtMap = new HashMap<>();
        jwtMap.put("phone", userEntity.getMobile());
        jwtMap.put("uid", userEntity.getId());
        jwtMap.put(JWTPayload.EXPIRES_AT, DateTime.of(System.currentTimeMillis() + Constants.JWT_TIME_OUT));
        // 载荷信息，密钥信息
        String token = JWTUtil.createToken(jwtMap, Constants.JWT_SECRET.getBytes());
        date.put("token", token);

        //设置探花传音次数
        redisTemplate.opsForValue().set(Constants.SOUND_UPPER_LIMIT + userEntity.getId(), "10");
        return date;
    }


    public UserEntity findUserById(Long uid) {
       return userService.findUserById(uid);
    }

    public void update(UserEntity entity) {
        userService.update(entity);
    }

    public UserEntity save(UserEntity entity) {
       return userService.addUser(entity);
    }
}
